package com.itcast.activiti.service.impl;

import cn.itcast.ic.common.exception.ICException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itcast.activiti.cmd.GetProcessCmd;
import com.itcast.activiti.cmd.GetProcessDefinitionCacheEntryCmd;
import com.itcast.activiti.constant.ErrorInfo;
import com.itcast.activiti.constant.NodeKeyTag;
import com.itcast.activiti.domain.AddSign;
import com.itcast.activiti.domain.RemoveSign;
import com.itcast.activiti.domain.StartProcessInstance;
import com.itcast.activiti.domain.TaskStart;
import com.itcast.activiti.entity.ApproveAddSign;
import com.itcast.activiti.event.AddSignEvent;
import com.itcast.activiti.event.CreateAttachmentEvent;
import com.itcast.activiti.event.NotifyTaskApplyEvent;
import com.itcast.activiti.service.*;
import com.itcast.activiti.utils.ActivitiPage;
import com.itcast.activiti.utils.SecurityUtil;
import com.itcast.activiti.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.*;
import org.activiti.engine.ManagementService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.deploy.ProcessDefinitionCacheEntry;
import org.activiti.engine.impl.persistence.entity.CommentEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ITaskRuntimeServiceImpl implements ITaskRuntimeService {
    @Autowired
    private TaskService taskService;
    @Autowired
    private SecurityUtil securityUtil;
    @Autowired
    private IHistoryService iHistoryService;
    @Autowired
    private IDeployRepositoryService iDeployRepositoryService;
    @Autowired
    private IProcessRuntimeService iProcessRuntimeService;
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private IActIdUserService iActIdUserService;
    @Autowired
    private IProcessControlService iProcessControlService;
    @Autowired
    private IApproveAddSignService iApproveAddSignService;
    @Autowired
    private ProcessEngine processEngine;

    @Override
    public ActivitiPage listTaskPage(ActivitiPage activitiPage) {
        JSONObject condition = activitiPage.getCondition();
        String businessKey = condition.getString(StartProcessInstance.Fields.businessKey);
        String assignee = condition.getString(TaskStart.Fields.assignee);
        String tenantId = condition.getString(TaskStart.Fields.tenantId);
        String candidateUser = condition.getString("candidateUser");
        List<String> processDefinitionKeys = (List<String>) condition.get("processDefinitionKeys");
        TaskQuery taskQuery = taskService.createTaskQuery();
        processDefinitionKeys = iProcessControlService.findProcessDefinitionKeys(processDefinitionKeys);
        if (StringUtils.hasText(businessKey)) {
            taskQuery.processInstanceBusinessKey(businessKey);
        }
        if (StringUtils.hasText(assignee)) {
            taskQuery.taskAssignee(assignee);
        }
        if (StringUtils.hasText(tenantId)) {
            taskQuery.taskTenantId(tenantId);
        }
        if (StringUtils.hasText(candidateUser)) {
            securityUtil.logInAs(candidateUser);
//            taskQuery.taskCandidateUser(candidateUser);
            taskQuery.taskCandidateOrAssigned(candidateUser);
        }
        if (processDefinitionKeys != null && !processDefinitionKeys.isEmpty()) {
            taskQuery.processDefinitionKeyIn(processDefinitionKeys);
        }
        Boolean filtrationSuspended = condition.getBoolean("filtrationSuspended");
        Integer startIndex = Math.toIntExact(activitiPage.getCurrent());
        Integer maxItems = Math.toIntExact(activitiPage.getSize());
        List<Map<String, Object>> resultList = returnListTask(taskQuery.listPage(startIndex, maxItems), filtrationSuspended);
        if (resultList == null || resultList.size() == 0) {
            return activitiPage;
        }
        activitiPage.setTotal(resultList.size());
        activitiPage.setRecords(resultList);
        return activitiPage;
    }

    @Override
    public List<Map<String, Object>> listMapTask(List<Task> taskList) {
        return returnListTask(taskList, null);
    }

    @Override
    public List<Task> listTask(String tenantId, String businessKey, String assignee) {
        List<Task> list = new ArrayList<>();
        // 获取用户任务
        List<Task> task1 = getTasksByAssignee(tenantId, businessKey, assignee);
        if (task1.size() != 0) {
            list.addAll(task1);
        }
        // 获取候选用户任务
        List<Task> task2 = getTasksByCandidateUser(tenantId, businessKey, assignee);
        if (task2.size() != 0) {
            list.addAll(task2);
        }
        return list;
    }


    @Override
    public List<Task> listTaskByProcessInstanceId(String processInstanceId) {
        return taskService.createTaskQuery()
                          .processInstanceId(processInstanceId)
                          .list();
    }

    @Override
    public String completeTaskApply(String tenantId, String businessKey, String assignee, TaskStart taskStart, Integer applyType) {
        List<Task> taskList1 = new ArrayList<>();
        List<Task> taskList2 = new ArrayList<>();
        if (applyType == null) {
            applyType = 1;
        }
        if (applyType == 22 || applyType == 33) {
            taskList1 = getTasksByAssignee(tenantId, businessKey, null);
        } else {
            // 获取用户任务
            taskList1 = getTasksByAssignee(tenantId, businessKey, assignee);
            // 获取候选用户任务
            taskList2 = getTasksByCandidateUser(tenantId, businessKey, assignee);
        }
        if (taskList1.size() == 0 && taskList2.size() == 0) throw new RuntimeException("当前用户没有需要处理的任务！");
        if (taskList1.size() != 0 && taskList2.size() != 0) throw new RuntimeException("流程出错，当前用户同时拥有本流程的会签和或签任务！");
        Task task2 = null;
        if (taskList2.size() != 0) {
            task2 = taskList2.get(0);
            // 拾取任务
            claimTask(task2.getId(), assignee);
        }
        // 获取当前任务
        Task task = taskList1.size() == 0 ? task2 : taskList1.get(0);
        if ("2".equals(task.getCategory())) throw new RuntimeException("知会节点不允许审批！");
        // 发起审批
        String taskId = taskApply(tenantId, businessKey, assignee, taskStart, task, applyType);
        // 自动完成后续的知会节点
        listJudgeAndComplateNotifyTask(getTasksByAssignee(tenantId, task.getProcessInstanceId(), null));
        return taskId;
    }

    @Override
    public String autoNextCompleteTaskApply(String tenantId, String businessKey, String assignee, TaskStart taskStart, Integer applyType, String lastTaskId) {
        taskStart.setAutoNextComplete(Boolean.TRUE);
        List<Task> taskList1 = new ArrayList<>();
        List<Task> taskList2 = new ArrayList<>();
        if (applyType == null) {
            applyType = 1;
        }
        if (applyType == 22 || applyType == 33) {
            taskList1 = getTasksByAssignee(tenantId, businessKey, null);
        } else {
            // 获取用户任务
            taskList1 = getTasksByAssignee(tenantId, businessKey, assignee);
            // 获取候选用户任务
            taskList2 = getTasksByCandidateUser(tenantId, businessKey, assignee);
        }
        if (taskList1.size() == 0 && taskList2.size() == 0 && Objects.nonNull(lastTaskId)) {
            taskStart.setEvent(null);
            taskStart.setAutoNextComplete(Boolean.FALSE);
            applicationContext.publishEvent(new NotifyTaskApplyEvent(this, tenantId, businessKey, assignee, taskStart, lastTaskId));
            return lastTaskId;
        }
        if (taskList1.size() == 0 && taskList2.size() == 0) throw new RuntimeException("当前用户没有需要处理的任务！");
        if (taskList1.size() != 0 && taskList2.size() != 0) throw new RuntimeException("流程出错，当前用户同时拥有本流程的会签和或签任务！");
        Task task2 = null;
        if (taskList2.size() != 0) {
            task2 = taskList2.get(0);
            // 拾取任务
            claimTask(task2.getId(), assignee);
        }
        // 获取当前任务
        Task task = taskList1.size() == 0 ? task2 : taskList1.get(0);
        if ("2".equals(task.getCategory())) throw new RuntimeException("知会节点不允许审批！");

        // 发起审批
        String taskId = taskApply(tenantId, businessKey, assignee, taskStart, task, applyType);
        // 自动完成后续的知会节点
        listJudgeAndComplateNotifyTask(getTasksByAssignee(tenantId, task.getProcessInstanceId(), null));
        lastTaskId = autoComplete(tenantId, businessKey, assignee, taskStart, applyType, taskId);
        taskStart.setEvent(null);
        taskStart.setAutoNextComplete(Boolean.FALSE);
        applicationContext.publishEvent(new NotifyTaskApplyEvent(this, tenantId, businessKey, assignee, taskStart, lastTaskId));
        return lastTaskId;
    }

    private String autoComplete(String tenantId, String businessKey, String assignee, TaskStart taskStart, Integer applyType, String lastTaskId) {
        taskStart.setComment("自动审批");
        if (!taskStart.getAutoNextComplete()) {
            return lastTaskId;
        }
        List<Task> tasksByAssignee = getTasksByAssignee(tenantId, businessKey, null);
        if (CollectionUtils.isEmpty(tasksByAssignee)) {
            return lastTaskId;
        }
        Set<String> historicAssignee = iHistoryService.getHistoricAssignee(businessKey, tenantId);
        for (Task task : tasksByAssignee) {
            List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());
            if (identityLinksForTask.size() > 1 || !historicAssignee.contains(identityLinksForTask.get(0).getUserId())) {
                return lastTaskId;
            }
            assignee = identityLinksForTask.get(0).getUserId();
            // 拾取任务
            claimTask(task.getId(), assignee);
            lastTaskId = taskApply(tenantId, businessKey, assignee, taskStart, task, applyType);
        }
        return autoComplete(tenantId, businessKey, assignee, taskStart, applyType, lastTaskId);
    }


    @Override
    public List<Map<String, Object>> listComment(String taskId) {
        List<Comment> commentList = taskService.getTaskComments(taskId);
        List<Map<String, Object>> resultList = new ArrayList<>();
        if (commentList.isEmpty()) {
            return null;
        }
        for (Comment comment : commentList) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("fullMessage", comment.getFullMessage());
            resultMap.put("time", TimeUtils.format(comment.getTime()));
            resultList.add(resultMap);
        }
        return resultList;
    }

    @Override
    public List<Attachment> listTaskAttachments(String taskId) {
        List<Attachment> taskAttachments = taskService.getTaskAttachments(taskId);
        if (taskAttachments == null || taskAttachments.size() == 0) {
            return null;
        }
        return taskAttachments;
    }

    @Override
    public List<Task> listJudgeAndComplateNotifyTask(List<Task> tasks) {
        if (tasks == null || tasks.size() == 0) return null;
        // 任务列表是同一节点产生的一批任务。只要有一个是知会节点，节点就是知会节点。实际上，知会节点按规则只产生一个任务。
        if ("2".equals(tasks.get(0).getCategory())) {
            for (Task task : tasks)
                // 完成当前任务
                complete(task.getId());
        } else {
            return tasks;
        }
        // 判断下一个节点
        return listJudgeAndComplateNotifyTask(listTaskByProcessInstanceId(tasks.get(0).getProcessInstanceId()));
    }

    @Override
    public String transferTask(String tenantId, String businessKey, String assignee, String assigneeOther) {
        Assert.hasText(businessKey, "businessKey is empty");
        List<Task> taskList = getTasksByAssignee(tenantId, businessKey, assignee);
        if (taskList.size() == 0) {
            Assert.notNull(null, assignee + " is not task");
        }
        Task task = taskList.get(0);
        String taskId = task.getId();
        this.transferTask(taskId, assigneeOther);
        return taskId;
    }

    @Override
    public String delegatedTask(String tenantId, String businessKey, String assignee, String delegatedAssignee) {
        Assert.hasText(businessKey, "businessKey is empty");
        Assert.hasText(assignee, "assignee is empty");
        List<Task> taskList = listTask(tenantId, businessKey, assignee);
        if (taskList.size() == 0) {
            Assert.notNull(null, assignee + " is not task");
        }
        Task task = taskList.get(0);
        String taskId = task.getId();
        taskService.delegateTask(taskId, StringUtils.hasText(delegatedAssignee) ? delegatedAssignee : assignee);
        return taskId;
    }

    @Override
    public String addSign(String tenantId, String businessKey, String assignee, AddSign addSign) {
        Set<String> assignees = iProcessRuntimeService.assignees(businessKey, tenantId);
        Set<String> retainSet = new HashSet<>(assignees);
        retainSet.retainAll(addSign.getUserEmails());
        if (!CollectionUtils.isEmpty(retainSet)) {
            throw new RuntimeException("用户已在当前审批流中");
        }
        List<Task> taskList1 = new ArrayList<>();
        List<Task> taskList2 = new ArrayList<>();
        Integer applyType = 1;
        // 获取用户任务
        taskList1 = getTasksByAssignee(tenantId, businessKey, assignee);
        // 获取候选用户任务
        taskList2 = getTasksByCandidateUser(tenantId, businessKey, assignee);
        if (taskList1.size() == 0 && taskList2.size() == 0) throw new RuntimeException("审批关系已发生变化，当前审批单处理人不是您");
        if (taskList1.size() != 0 && taskList2.size() != 0) throw new RuntimeException("流程出错，当前用户同时拥有本流程的会签和或签任务！");
        Task task2 = null;
        if (taskList2.size() != 0) {
            task2 = taskList2.get(0);
        }
        // 获取当前任务
        Task task = taskList1.size() == 0 ? task2 : taskList1.get(0);
        if ("2".equals(task.getCategory())) throw new RuntimeException("知会节点不允许审批！");
        TaskEntity taskEntity = (TaskEntity) task;
        iActIdUserService.addUserByEmails(addSign.getUserEmails());
        iProcessControlService.addSign(assignee, taskEntity, addSign);
        applicationContext.publishEvent(new AddSignEvent(this, StringUtils.hasText(addSign.getTenantId()) ? addSign.getTenantId() : "PMIS", businessKey, assignee, addSign));
        return "success";
    }

    @Override
    public String removeSign(String tenantId, String businessKey, String assignee, RemoveSign removeSign) {
        ProcessInstance processInstance = iProcessRuntimeService.getProcessInstanceByBusinessKey(businessKey, tenantId);
        List<ApproveAddSign> approveAddSigns = iApproveAddSignService.findByProcDefId(processInstance.getProcessDefinitionId());
        Map<String, ApproveAddSign> approveAddSignMap = approveAddSigns.stream().collect(Collectors.toMap(ApproveAddSign::getId, t -> t));
        ApproveAddSign approveAddSign = approveAddSignMap.get(removeSign.getTaskDefinitionKey().replace(NodeKeyTag.USERTASK_PREFIX, ""));
        if (approveAddSign == null) {
            throw new ICException(new ErrorInfo("节点不是加签节点，不允许减签！"));
        }
        if (!approveAddSign.getCreatedBy().equals(assignee)) {
            throw new ICException(new ErrorInfo("节点非创建人创建，不允许减签"));
        }
        iProcessControlService.removeSign(assignee, processInstance, removeSign);
        return "success";
    }

    @Override
    public Map<String, Object> current(String tenantId, String businessKey, String assignee) {
        TaskQuery taskQuery = taskService.createTaskQuery().processInstanceBusinessKey(businessKey);
        if (StringUtils.hasText(assignee)) {
            taskQuery.taskCandidateOrAssigned(assignee);
        }
        if (StringUtils.hasText(tenantId)) {
            taskQuery.taskTenantId(tenantId);
        }
        List<Task> tasks = taskQuery.list();
        if (CollectionUtils.isEmpty(tasks)) {
            return Collections.emptyMap();
        }
        Map<String, Object> map = new HashMap<>();
        Task task = tasks.get(0);
        ManagementService managementService = processEngine.getManagementService();
        managementService.executeCommand(new GetProcessCmd(task.getProcessDefinitionId()));
        ProcessDefinitionCacheEntry processDefinitionCacheEntry = managementService.executeCommand(new GetProcessDefinitionCacheEntryCmd(task.getProcessDefinitionId(), processEngine));
        Process process = processDefinitionCacheEntry.getProcess();
        FlowElement flowElement = process.getFlowElement(task.getTaskDefinitionKey());
        if (flowElement instanceof UserTask) {
            UserTask userTask = (UserTask) flowElement;
            map.put("hasMultiInstanceLoopCharacteristics", userTask.hasMultiInstanceLoopCharacteristics());
        }
        return map;
    }

    // 审批
    private String taskApply(String tenantId, String businessKey, String assignee, TaskStart taskStart, Task task, Integer applyType) {
        Assert.notNull(task, assignee + " is not task");
        String taskId = task.getId();
        // 添加变量参数
        HashMap<String, Object> variables = setVariables(taskStart, taskId);
        // 添加申请内容
        String commentId = addComment(assignee, task.getProcessInstanceId(), taskId, CommentEntity.TYPE_COMMENT, taskStart.getComment());
        try {
            // 添加附件
            applicationContext.publishEvent(new CreateAttachmentEvent(this, taskId, task.getProcessInstanceId(), taskStart.getAttachment()));
            // 有任务时，完成任务
            // 1：审批通过（默认））2：驳回到发起人）3：驳回上一级）
            if (applyType == null || applyType == 1) {
                complete(taskId);
            } else if (applyType == 2 || applyType == 22) {
                backTask(task, 0);
            } else if (applyType == 3 || applyType == 33) {
                backTask(task, 1);
            }

            // 审批结果通知
            applicationContext.publishEvent(new NotifyTaskApplyEvent(this, tenantId, businessKey, assignee, taskStart, taskId));

            log.info("apply success {} {}", taskId, JSON.toJSON(taskStart));
        } catch (Exception e) {
            delComment(commentId, assignee);
//            removeVariable(variables, taskId);
            throw new RuntimeException(e.getMessage());
        }
        return taskId;
    }

    // 拾取任务
    private String claimTask(String taskId, String assignee) {
        try {
            taskService.claim(taskId, assignee);
        } catch (Exception e) {
            log.warn("拾取任务失败 {} {}", taskId, assignee);
        }
        return taskId;
    }

    // 完成任务
    private void complete(String taskId) {
        taskService.complete(taskId);
    }

    // 添加申请内容
    private String addComment(String assignee, String processInstanceId, String taskId, String type, String comment) {
        if (!StringUtils.hasText(comment)) {
            return null;
        }
        try {
            Authentication.setAuthenticatedUserId(assignee);
            Comment comment1 = taskService.addComment(taskId, processInstanceId, type, comment);
            return comment1.getId();
        } catch (Exception e) {
            log.warn("add comment Exception {}", e.getMessage());
        }
        return null;
    }

    // 添加申请内容
    private void delComment(String commentId, String assignee) {
        if (!StringUtils.hasText(commentId)) {
            return;
        }
        try {
            Authentication.setAuthenticatedUserId(assignee);
            taskService.deleteComment(commentId);
        } catch (Exception e) {
            log.warn("add comment Exception {}", e.getMessage());
        }
    }

    // 添加变量参数
    private HashMap<String, Object> setVariables(TaskStart taskStart, String taskId) {
        HashMap<String, Object> variables = taskStart.getVariables();
        if (variables == null) {
            variables = new HashMap<>();
        }
        variables.put(TaskStart.Fields.audit, taskStart.getAudit() == null ? true : taskStart.getAudit());
        taskService.setVariables(taskId, variables);
        return variables;
    }

    // 删除变量参数
    private void removeVariable(HashMap<String, Object> variables, String taskId) {
        if (variables == null) {
            return;
        }
        for (String key : variables.keySet()) {
            try {
                taskService.removeVariable(taskId, key);
            } catch (Exception e) {
            }
        }
    }

    private List<Map<String, Object>> returnListTask(List<Task> taskList, Boolean filtrationSuspended) {
        if (taskList == null || taskList.size() == 0) {
            return null;
        }
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (Task task : taskList) {
            if (filtrationSuspended != null && filtrationSuspended && task.isSuspended()) {
                continue;
            }
            String processInstanceId = task.getProcessInstanceId();
            DelegationState delegationState = task.getDelegationState();
            SortedMap<String, Object> resultMap = new TreeMap<>();
            resultMap.put("id", task.getId());
            resultMap.put("name", task.getName());
            resultMap.put("createTime", TimeUtils.format(task.getCreateTime()));
            resultMap.put("dueDate", TimeUtils.format(task.getDueDate()));
            if (StringUtils.hasText(task.getAssignee())) {
                String userName = iActIdUserService.getUserNameByemail(task.getAssignee());
                if (!StringUtils.hasText(userName)) {
                    userName = task.getAssignee();
                }
                resultMap.put("assignee", userName);
            }
            resultMap.put("email", task.getAssignee());
            resultMap.put("processInstanceId", processInstanceId);
            resultMap.put("executionId", task.getExecutionId());
            resultMap.put("processDefinitionId", task.getProcessDefinitionId());
            resultMap.put("description", task.getDescription());
            resultMap.put("priority", task.getPriority());
            resultMap.put("owner", task.getOwner());
            resultMap.put("suspended", task.isSuspended());
            resultMap.put("delegationState", delegationState);
            if (StringUtils.hasText(processInstanceId)) {
                ProcessInstance processInstance = iProcessRuntimeService.getProcessInstanceByProcessInstanceId(processInstanceId);
                if (processInstance != null) {
                    resultMap.put("processInstanceName", processInstance.getName());
                    resultMap.put("businessKey", processInstance.getBusinessKey());
                }
            }
            resultList.add(resultMap);
        }
        return resultList;
    }

    // 回退任务（默认：驳回到上一级）
    private void backTask(Task task, Integer NodeRank) {
        String processInstanceId = task.getProcessInstanceId();
        // 取得所有历史任务按时间降序排序
        List<HistoricTaskInstance> htiList = iHistoryService.getHistoryTaskListByProcessInstanceId(processInstanceId, Sort.Direction.DESC.name());
        if (htiList.isEmpty() || htiList.size() < 2) {
            return;
        }
        if (NodeRank == null) {
            // 驳回到上一级
            NodeRank = 1;
        } else if (NodeRank == 0) {
            // 驳回到发起人
            NodeRank = htiList.size() - 1;
        }
        //上一个任务
        HistoricTaskInstance lastTask = htiList.get(NodeRank);
        // 当前任务
        HistoricTaskInstance curTask = htiList.get(0);
        // 当前节点的executionId
        String curExecutionId = curTask.getExecutionId();
        // 上个节点的taskId
        String lastTaskId = lastTask.getId();
        Assert.hasText(lastTaskId, "last task is null");
        // 上个节点的executionId
        String lastExecutionId = lastTask.getExecutionId();
        String processDefinitionId = lastTask.getProcessDefinitionId();
        BpmnModel bpmnModel = iDeployRepositoryService.getBpmnModelByProcessDefinitionId(processDefinitionId);
        String lastActivityId = null;
        List<HistoricActivityInstance> haiFinishedList = iHistoryService.getHistoricActivityInstanceByExecutionId(lastExecutionId);
        for (HistoricActivityInstance hai : haiFinishedList) {
            if (lastTaskId.equals(hai.getTaskId())) {
                lastActivityId = hai.getActivityId();
                break;
            }
        }
        // 得到上个节点的信息
        FlowNode lastFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(lastActivityId);
        // 取得当前节点的信息
        Execution execution = iProcessRuntimeService.getExecution(curExecutionId);
        String curActivityId = execution.getActivityId();
        FlowNode curFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(curActivityId);
        //记录当前节点的原活动方向
        List<SequenceFlow> oriSequenceFlows = new ArrayList<>();
        oriSequenceFlows.addAll(curFlowNode.getOutgoingFlows());
        //清理活动方向
        curFlowNode.getOutgoingFlows().clear();
        //建立新方向
        List<SequenceFlow> newSequenceFlowList = new ArrayList<>();
        SequenceFlow newSequenceFlow = new SequenceFlow();
        newSequenceFlow.setId("newSequenceFlowId");
        newSequenceFlow.setSourceFlowElement(curFlowNode);
        newSequenceFlow.setTargetFlowElement(lastFlowNode);
        newSequenceFlowList.add(newSequenceFlow);
        curFlowNode.setOutgoingFlows(newSequenceFlowList);
        // 完成任务
        complete(task.getId());
        //恢复原方向
        curFlowNode.setOutgoingFlows(oriSequenceFlows);
        List<Task> taskList = listTaskByProcessInstanceId(processInstanceId);
        if (taskList != null && taskList.size() != 0) {
            Task nextTask = taskList.get(0);
            // 设置执行人
            if (nextTask != null) {
                transferTask(nextTask.getId(), lastTask.getAssignee());
            }
        }
    }

    // 设置执行人
    private String transferTask(String taskId, String assigneeOther) {
        taskService.setAssignee(taskId, assigneeOther);
        return taskId;
    }

    // 获取用户任务
    private List<Task> getTasksByAssignee(String tenantId, String businessKey, String assignee) {
        TaskQuery taskQuery1 = taskService.createTaskQuery().processInstanceBusinessKey(businessKey);
        if (StringUtils.hasText(assignee)) {
            taskQuery1.taskAssignee(assignee);
        }
        if (StringUtils.hasText(tenantId)) {
            taskQuery1.taskTenantId(tenantId);
        }
        return taskQuery1.list();
    }

    // 获取候选用户任务
    private List<Task> getTasksByCandidateUser(String tenantId, String businessKey, String assignee) {
        TaskQuery taskQuery2 = taskService.createTaskQuery().processInstanceBusinessKey(businessKey);
        if (StringUtils.hasText(assignee)) {
            securityUtil.logInAs(assignee);
            taskQuery2.taskCandidateUser(assignee);
        }
        if (StringUtils.hasText(tenantId)) {
            taskQuery2.taskTenantId(tenantId);
        }
        return taskQuery2.list();
    }
}
